package com.example.embed.calcite.service;

import com.google.common.collect.Multimap;
import org.apache.calcite.schema.Function;
import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.impl.AbstractSchema;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 内存模式（Schema）实现类
 * <p>
 * 继承自Calcite的AbstractSchema，用于在内存中管理和提供表结构，
 * 支持注册内存表并向Calcite提供表访问能力
 * </p>
 *
 * @author zwg
 * @date 2025/7/7 18:02
 */
public class MemorySchema extends AbstractSchema implements Serializable {
    /**
     * 存储表名到表对象的映射关系
     */
    private Map<String, Table> metaTableMap = new HashMap<>();

    /**
     * 默认构造函数
     * 创建一个空的内存模式实例
     */
    public MemorySchema() {
    }

    /**
     * 注册内存表到当前模式
     * <p>
     * 将指定的内存表添加到模式中，使用表名作为键
     * </p>
     *
     * @param memoryTable 要注册的内存表实例
     */
    public void registerTable(MemoryTable memoryTable) {
        this.metaTableMap.put(memoryTable.getTableName(), memoryTable);
    }

    /**
     * 创建内存模式并添加带有数据的表
     * <p>
     * 便捷工厂方法，创建一个新的内存模式并添加指定名称和数据的表
     * </p>
     *
     * @param tableName 表名
     * @param items     表数据，每行数据为一个Map对象
     * @return 创建的内存模式实例
     */
    public static MemorySchema create(String tableName, List<Map<String, Object>> items) {
        MemorySchema memorySchema = new MemorySchema();
        MemoryTable memoryTable = new MemoryTable(tableName, items);
        memorySchema.registerTable(memoryTable);
        return memorySchema;
    }

    /**
     * 创建内存模式并添加空表
     * <p>
     * 便捷工厂方法，创建一个新的内存模式并添加指定名称的空表
     * </p>
     *
     * @param tableName 表名
     * @return 创建的内存模式实例
     */
    public static MemorySchema create(String tableName) {
        MemorySchema memorySchema = new MemorySchema();
        MemoryTable memoryTable = new MemoryTable(tableName);
        memorySchema.registerTable(memoryTable);
        return memorySchema;
    }

    /**
     * 获取表映射
     * <p>
     * 重写父类方法，向Calcite提供当前模式中所有表的映射关系
     * </p>
     *
     * @return 表名到表对象的映射
     */
    @Override
    protected Map<String, Table> getTableMap() {
        return this.metaTableMap;
    }

    /**
     * 获取函数映射
     * <p>
     * 重写父类方法，提供当前模式中注册的函数信息
     * 目前使用父类默认实现，可根据需要扩展自定义函数
     * </p>
     *
     * @return 函数名到函数对象的多值映射
     */
    @Override
    protected Multimap<String, Function> getFunctionMultimap() {
        return super.getFunctionMultimap();
    }
}
